"""
平板端控制器文件
处理平板端相关的HTTP请求，包括数据上传和实时分析查询接口
使用FastAPI的APIRouter定义路由，实现同步返回分析结果和实时分析结果获取
原理：平板端作为数据转发器，服务端进行实时MNE+YASA分析，提供即时反馈
"""

from __future__ import annotations
from fastapi import APIRouter, HTTPException, Depends, BackgroundTasks
from pydantic import BaseModel, Field, validator
from typing import Optional, List, Dict, Any
from datetime import datetime
import asyncio
import logging
import time
import numpy as np

from ..models.tablet_data_models import (
    TabletBrainWaveData, 
    TabletDataBuffer, 
    TabletDataValidator,
    TabletDataConverter,
    get_global_buffer
)
from ..models.brain_wave_data import BrainWaveData, FrequencyData, TimeSeriesData
from ..service.tablet_service import TabletService
from ..utils.response import success_response, error_response, ResponseCode

# 配置日志
logger = logging.getLogger(__name__)

# 创建路由器
tablet_router = APIRouter(prefix="/tablet", tags=["平板端接口"])

# 创建服务实例
tablet_service = TabletService()

# 统一的异步云端存储方法
async def _send_analysis_result_to_cloud_async(
    session_id: str, 
    room_id: str, 
    analysis_result: Dict[str, Any],
    processed_data: List[Dict[str, Any]] = None
) -> None:
    """
    统一的异步云端存储方法
    将controller层的分析结果发送到云端存储，不阻塞主要业务流程
    
    Args:
        session_id: 会话ID
        room_id: 房间ID  
        analysis_result: service层返回的分析结果
        processed_data: 处理后的原始数据（可选）
        
    原理：
    1. 解包service层返回的分析结果
    2. 构建BrainWaveData对象
    3. 调用云端API服务异步上传
    4. 记录上传结果日志
    """
    try:
        # 导入云端API服务
        from ..service.cloud_api import get_cloud_api_service
        cloud_api_service = get_cloud_api_service()
        
        # 构建云端上传数据
        from ..models.brain_wave_data import BrainWaveData, FrequencyData, TimeSeriesData
        from datetime import datetime
        
        # 从缓存中获取处理后的数据，如果没有传入则从service获取
        if processed_data is None:
            processed_data = tablet_service.session_data_cache.get(session_id, [])
        
        if processed_data:
            # 直接从analysis_result提取5频域数据，无需转换为8频域格式
            frequency_bands = analysis_result.get('frequency_bands', {})
            
            # 创建RealtimeDataPoint对象，直接使用5频域格式
            from ..models.cloud_storage_models import RealtimeDataPoint, RealtimeDataRequest
            
            realtime_point = RealtimeDataPoint(
                timestamp=datetime.now().timestamp(),
                state=analysis_result.get('sleep_stage', 'unknown'),
                confidence=analysis_result.get('confidence', 0.0),
                delta=frequency_bands.get('delta', 0.2),
                theta=frequency_bands.get('theta', 0.2),
                alpha=frequency_bands.get('alpha', 0.02),
                beta=frequency_bands.get('beta', 0.2),
                gamma=frequency_bands.get('gamma', 0.2)
            )
            
            # 构建实时数据请求
            realtime_request = RealtimeDataRequest(
                session_id=session_id,
                room_id=room_id,
                user_id="default_user",
                data=[realtime_point]
            )
            
            # 发送到云端存储
            response = cloud_api_service.send_realtime_data_to_cloud_storage(
                session_id=session_id,
                realtime_request=realtime_request
            )
            
            if response:
                response_id = response.data.get('id') if response.data else 'unknown'
                analysis_type = analysis_result.get('analysis_type', 'unknown')
                logger.info(f"[Controller] 分析结果成功上传到云端: session_id={session_id}, response_id={response_id}, analysis_type={analysis_type}")
            else:
                logger.warning(f"[Controller] 分析结果上传到云端失败: session_id={session_id}")
        else:
            logger.warning(f"[Controller] 无可用数据进行云端上传: session_id={session_id}")
            
    except Exception as e:
        logger.warning(f"[Controller] 云端上传异常: session_id={session_id}, error={str(e)}")
        # 不抛出异常，避免影响主要业务流程

# 简化的数据上传请求模型
class TabletBrainWaveRequest(BaseModel):
    """平板端脑波数据上传模型 - 每秒一次请求"""
    session_id: str = Field(..., min_length=1, description="会话ID")
    room_id: str = Field(..., min_length=1, description="房间ID")
    timestamp: int = Field(..., description="数据时间戳（毫秒）")
    
    # 原始EEG数据 - 256Hz采样率，支持1-120秒的数据（256-30720个数据点）
    raw_value: List[int] = Field(..., min_items=256, max_items=30720, description="原始EEG数据值数组，256Hz采样率，支持1-120秒数据")
    
    # 8个频段功率数据 (每秒一个值)
    delta: int = Field(..., ge=0, description="Delta波段功率 (0.5-4Hz)")
    theta: int = Field(..., ge=0, description="Theta波段功率 (4-8Hz)")
    low_alpha: int = Field(..., ge=0, description="低Alpha波段功率 (8-10Hz)")
    high_alpha: int = Field(..., ge=0, description="高Alpha波段功率 (10-13Hz)")
    low_beta: int = Field(..., ge=0, description="低Beta波段功率 (13-17Hz)")
    high_beta: int = Field(..., ge=0, description="高Beta波段功率 (17-30Hz)")
    low_gamma: int = Field(..., ge=0, description="低Gamma波段功率 (30-40Hz)")
    mid_gamma: int = Field(..., ge=0, description="中Gamma波段功率 (40-100Hz)")
    
    # NeuroSky算法输出
    attention: int = Field(..., ge=0, le=100, description="注意力指数 (0-100)")
    meditation: int = Field(..., ge=0, le=100, description="冥想指数 (0-100)")
    
    # 信号质量指标
    poor_signal: int = Field(..., ge=0, le=200, description="信号质量 (0=好信号, 200=无信号)")
    blink_strength: int = Field(..., ge=0, le=255, description="眨眼强度 (0-255)")


class RealtimeAnalysisResponse(BaseModel):
    """实时分析响应模型"""
    status: str = Field(..., description="分析状态：processing/completed/error/no_data")
    id: str = Field(..., description="会话ID")
    timestamp: int = Field(..., description="响应时间戳（毫秒）")
    message: Optional[str] = Field(None, description="状态消息")
    
    # 分析结果字段（仅在status为completed时有值）
    sleep_stage: Optional[str] = Field(None, description="睡眠阶段：wake/n1/n2/n3/rem")
    confidence: Optional[float] = Field(None, ge=0.0, le=1.0, description="置信度")
    frequency_bands: Optional[Dict[str, float]] = Field(None, description="5频域功率比例")
    completion_time: Optional[int] = Field(None, description="分析完成时间戳（毫秒）")
    data_count: Optional[int] = Field(None, description="分析的数据点数量")
    
    # 处理状态字段（仅在status为processing时有值）
    start_time: Optional[int] = Field(None, description="分析开始时间戳（毫秒）")
    elapsed_seconds: Optional[float] = Field(None, description="已经过时间（秒）")
    estimated_completion_seconds: Optional[float] = Field(None, description="预估剩余时间（秒）")
    
    # 错误信息字段（仅在status为error时有值）
    error: Optional[str] = Field(None, description="错误信息")
    error_time: Optional[int] = Field(None, description="错误发生时间戳（毫秒）")
    
    # 兼容性字段（已弃用）
    analysis_available: Optional[bool] = Field(None, description="是否有分析结果可用（已弃用，使用status判断）")


class EpochResult(BaseModel):
    """单个epoch分析结果"""
    epoch_index: int = Field(..., description="Epoch索引")
    start_time: str = Field(..., description="Epoch开始时间")
    end_time: str = Field(..., description="Epoch结束时间")
    sleep_stage: str = Field(..., description="睡眠阶段：wake/n1/n2/n3/rem")
    confidence: float = Field(..., ge=0.0, le=1.0, description="置信度")

class SyncAnalysisResponse(BaseModel):
    """同步分析响应模型"""
    success: bool = Field(True, description="是否成功")
    message: str = Field("数据分析完成", description="响应消息")
    session_id: str = Field(..., description="会话ID")
    timestamp: int = Field(..., description="响应时间戳（毫秒）")
    received_data_points: int = Field(..., description="接收到的数据点数量")
    
    # 分析结果字段 - 当前（最新）结果
    sleep_stage: Optional[str] = Field(None, description="当前睡眠阶段：wake/n1/n2/n3/rem")
    confidence: Optional[float] = Field(None, ge=0.0, le=1.0, description="当前置信度")
    frequency_bands: Optional[Dict[str, float]] = Field(None, description="频域功率比例")
    
    # 所有epochs的详细结果
    epochs: Optional[List[EpochResult]] = Field(None, description="所有epochs的分析结果")
    total_epochs: Optional[int] = Field(None, description="总epoch数量")
    
    # 性能指标
    analysis_duration_ms: Optional[int] = Field(None, description="分析耗时（毫秒）")
    buffer_size: int = Field(..., description="当前缓冲区大小")
    yasa_available: bool = Field(True, description="YASA分析器是否可用")

@tablet_router.post("/brainwave/sync", response_model=SyncAnalysisResponse,
                    summary="平板端同步分析", description="平板端上传脑波数据并同步返回分析结果")
async def upload_brainwave_data_sync(request: TabletBrainWaveRequest):
    """
    平板端同步分析接口
    
    接收脑波数据并立即进行分析，同步返回分析结果。
    与异步接口不同，此接口会等待分析完成后返回结果。
    
    Args:
        request: 平板端脑波数据请求
        
    Returns:
        SyncAnalysisResponse: 包含分析结果的响应
    """
    try:
        start_time = time.time()
        
        # 调试输出：接收到的数据基本信息
        logger.info("=== 同步分析接口数据接收调试 ===")
        logger.info(f"接口被调用，开始处理请求...")
        
        # 检查request对象是否正确创建
        logger.info(f"request对象类型: {type(request)}")
        logger.info(f"request对象是否为None: {request is None}")
        
        # 逐个字段检查和输出
        try:
            logger.info(f"session_id: {request.session_id} (类型: {type(request.session_id)})")
        except Exception as e:
            logger.error(f"获取session_id失败: {e}")
            
        try:
            logger.info(f"room_id: {request.room_id} (类型: {type(request.room_id)})")
        except Exception as e:
            logger.error(f"获取room_id失败: {e}")
            
        try:
            logger.info(f"timestamp: {request.timestamp} (类型: {type(request.timestamp)})")
        except Exception as e:
            logger.error(f"获取timestamp失败: {e}")
            
        try:
            logger.info(f"raw_value长度: {len(request.raw_value)} (类型: {type(request.raw_value)})")
        except Exception as e:
            logger.error(f"获取raw_value失败: {e}")
        
        # 调试输出：脑波频段数据
        try:
            logger.info(f"delta: {request.delta} (类型: {type(request.delta)})")
            logger.info(f"theta: {request.theta} (类型: {type(request.theta)})")
            logger.info(f"low_alpha: {request.low_alpha} (类型: {type(request.low_alpha)})")
            logger.info(f"high_alpha: {request.high_alpha} (类型: {type(request.high_alpha)})")
            logger.info(f"low_beta: {request.low_beta} (类型: {type(request.low_beta)})")
            logger.info(f"high_beta: {request.high_beta} (类型: {type(request.high_beta)})")
            logger.info(f"low_gamma: {request.low_gamma} (类型: {type(request.low_gamma)})")
            logger.info(f"mid_gamma: {request.mid_gamma} (类型: {type(request.mid_gamma)})")
        except Exception as e:
            logger.error(f"获取脑波频段数据失败: {e}")
        
        # 调试输出：状态指标
        try:
            logger.info(f"attention: {request.attention} (类型: {type(request.attention)})")
            logger.info(f"meditation: {request.meditation} (类型: {type(request.meditation)})")
            logger.info(f"poor_signal: {request.poor_signal} (类型: {type(request.poor_signal)})")
            logger.info(f"blink_strength: {request.blink_strength} (类型: {type(request.blink_strength)})")
        except Exception as e:
            logger.error(f"获取状态指标失败: {e}")
        
        # 调试输出：raw_value数据样本（前5个和后5个）
        try:
            if hasattr(request, 'raw_value') and request.raw_value and len(request.raw_value) > 0:
                logger.info(f"raw_value前5个值: {request.raw_value[:5]}")
                logger.info(f"raw_value后5个值: {request.raw_value[-5:]}")
                logger.info(f"raw_value数据类型检查: {[type(x) for x in request.raw_value[:3]]}")
        except Exception as e:
            logger.error(f"获取raw_value样本数据失败: {e}")
        
        # 数据验证和转换（复用现有逻辑）
        raw_data = request.raw_value
        if len(raw_data) < 256:
            logger.error(f"数据验证失败: raw_data长度 {len(raw_data)} < 256")
            raise HTTPException(status_code=400, detail="原始数据至少需要256个数据点（1秒数据）")
        if len(raw_data) > 30720:
            logger.error(f"数据验证失败: raw_data长度 {len(raw_data)} > 30720")
            raise HTTPException(status_code=400, detail="原始数据不能超过30720个数据点（120秒数据）")
        
        # 直接使用TabletBrainWaveData，不需要转换为BrainWaveData
        from ..models.tablet_data_models import RawValuePoint
        raw_value_points = [
            RawValuePoint(value=value, timestamp=request.timestamp + i)
            for i, value in enumerate(raw_data)
        ]
        
        tablet_data = TabletBrainWaveData(
            session_id=request.session_id,
            room_id=request.room_id,
            timestamp=request.timestamp,
            raw_value=raw_value_points,
            poor_signal=request.poor_signal,
            attention=request.attention,
            meditation=request.meditation,
            delta=request.delta,
            theta=request.theta,
            low_alpha=request.low_alpha,
            high_alpha=request.high_alpha,
            low_beta=request.low_beta,
            high_beta=request.high_beta,
            low_gamma=request.low_gamma,
            mid_gamma=request.mid_gamma,
            blink_strength=request.blink_strength
        )
        
        # 添加到全局缓冲区
        buffer = get_global_buffer()
        buffer.add_data(tablet_data)
        current_buffer_size = len(buffer.get_all_data())
        
        # 将数据添加到tablet_service的session_data_cache中
        from ..models.tablet_data_models import TabletDataConverter
        internal_data = TabletDataConverter.to_internal_format(tablet_data)
        tablet_service.session_data_cache[request.session_id].append(internal_data)
        
        # 同步调用分析服务
        analysis_result = await tablet_service.process_data_and_analyze_sync(
            request.session_id, 
            request.room_id
        )
        
        # 统一的云端上传逻辑 - 使用新的统一方法
        if analysis_result and analysis_result.get('success'):
            try:
                 # 获取处理后的数据
                 processed_data = tablet_service.session_data_cache.get(request.session_id, [])
                 
                 # 异步发送分析结果到云端存储（不阻塞主要业务流程）
                 asyncio.create_task(
                     _send_analysis_result_to_cloud_async(
                         session_id=request.session_id,
                         room_id=request.room_id,
                         analysis_result=analysis_result,
                         processed_data=processed_data
                     )
                 )
            except Exception as cloud_error:
                 logger.warning(f"[Controller] 创建云端上传任务失败: session_id={request.session_id}, error={str(cloud_error)}")
        
        analysis_duration_ms = int((time.time() - start_time) * 1000)
        
        # 构建响应
        response = SyncAnalysisResponse(
            session_id=request.session_id,
            timestamp=int(time.time() * 1000),
            received_data_points=len(raw_data),
            buffer_size=current_buffer_size,
            analysis_duration_ms=analysis_duration_ms
        )
        
        # 填充分析结果
        if analysis_result and analysis_result.get('success'):
            response.sleep_stage = analysis_result.get('sleep_stage')
            response.confidence = analysis_result.get('confidence')
            response.frequency_bands = analysis_result.get('frequency_bands')
            
            # 添加epochs详细信息
            epoch_results = analysis_result.get('epoch_results', [])
            if epoch_results:
                response.epochs = [
                    EpochResult(
                        epoch_index=epoch['epoch_index'],
                        start_time=epoch['start_time'].isoformat() if hasattr(epoch['start_time'], 'isoformat') else str(epoch['start_time']),
                        end_time=epoch['end_time'].isoformat() if hasattr(epoch['end_time'], 'isoformat') else str(epoch['end_time']),
                        sleep_stage=epoch['sleep_stage'],
                        confidence=epoch['confidence']
                    )
                    for epoch in epoch_results
                ]
                response.total_epochs = len(epoch_results)
        
        print(f"response: {response}")
        return response
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"同步分析处理失败: {str(e)}")
        logger.error(f"异常详细信息: {type(e).__name__}: {str(e)}")
        import traceback
        logger.error(f"异常堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"同步分析处理失败: {str(e)}")


@tablet_router.get("/realtime/{id}", response_model=RealtimeAnalysisResponse,
                   summary="获取实时分析数据", description="获取指定会话的最新YASA分析结果和频域数据")
async def get_realtime_analysis(
    id: str,
    room_id: Optional[str] = None,
    user_id: Optional[str] = None
):
    """
    获取实时分析数据接口
    
    支持高频查询，返回最新的YASA分析结果和频域数据。
    如果分析正在进行中，返回processing状态；如果分析完成，返回completed状态和结果。
    
    Args:
        id: 会话ID
        room_id: 房间ID（可选）
        user_id: 用户ID（可选）
        
    Returns:
        RealtimeAnalysisResponse: 实时分析响应
    """
    try:
        # 获取最新的分析结果
        analysis_result = await tablet_service.get_latest_analysis_result(id)
        
        current_timestamp = int(time.time() * 1000)
        
        if not analysis_result:
            return RealtimeAnalysisResponse(
                status="no_data",
                id=id,
                timestamp=current_timestamp,
                message="暂无分析数据"
            )
        
        # 检查分析状态
        if analysis_result.get('status') == 'processing':
            return RealtimeAnalysisResponse(
                status="processing",
                id=id,
                timestamp=current_timestamp,
                message="分析进行中",
                start_time=analysis_result.get('start_time'),
                elapsed_seconds=analysis_result.get('elapsed_seconds'),
                estimated_completion_seconds=analysis_result.get('estimated_completion_seconds')
            )
        elif analysis_result.get('status') == 'error':
            return RealtimeAnalysisResponse(
                status="error",
                id=id,
                timestamp=current_timestamp,
                message="分析出错",
                error=analysis_result.get('error'),
                error_time=analysis_result.get('error_time')
            )
        else:
            # 分析完成，返回结果
            return RealtimeAnalysisResponse(
                status="completed",
                id=id,
                timestamp=current_timestamp,
                message="分析完成",
                sleep_stage=analysis_result.get('sleep_stage'),
                confidence=analysis_result.get('confidence'),
                frequency_bands=analysis_result.get('frequency_bands'),
                completion_time=analysis_result.get('completion_time'),
                data_count=analysis_result.get('data_count')
            )
            
    except Exception as e:
        logger.error(f"获取实时分析数据失败: {str(e)}")
        return RealtimeAnalysisResponse(
            status="error",
            id=id,
            timestamp=int(time.time() * 1000),
            message="服务器内部错误",
            error=str(e),
            error_time=int(time.time() * 1000)
        )